package cn.aihongbo.kmp.base.net

import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.UserAgent
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.plugins.logging.DEFAULT
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json
import io.ktor.util.appendIfNameAbsent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.json.Json

val BASE_API_URL = "https://api-gw.test.huangbaoche.com/capp"
const val API_CODE_SUCCESS = "200"

class HNet {

    companion object {
        val ins by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { HNet() }
    }

    val client = HttpClient {
        install(ContentNegotiation) {
            json(Json {
                prettyPrint = true
                ignoreUnknownKeys = true
                isLenient = true
            })
        }
        install(HttpTimeout) {
            requestTimeoutMillis = 30000
            connectTimeoutMillis = 30000
        }
        install(UserAgent) {
            agent = "CAPP-KMP/V1.0.0"
        }
        defaultRequest {
            url(BASE_API_URL)
            contentType(ContentType.Application.Json)
            headers.appendIfNameAbsent("X-CCLX-Api-Key", "1f547d5c-5b3a-4fe2-bc50-e1539112ca60")
            headers.appendIfNameAbsent("ut", "5b4c775817bb1de029acefb121338e9f")
            headers.appendIfNameAbsent("ak", "c677468e00b5d3b8d1589d7bb4244352")
        }
        install(Logging) {
            logger = Logger.DEFAULT
            level = LogLevel.ALL
            filter { request ->
                request.url.host.contains("huangbaoche.com")
            }
            sanitizeHeader { header -> header == HttpHeaders.Authorization }
        }
    }

    fun close() {
        client.close()
    }

    inline fun <reified T> get(url: String, params: Map<String, String> = emptyMap()): Flow<T> {
        return flow {
            val response = client.get("${BASE_API_URL}${url}") {
                params.forEach { parameter(it.key, it.value) }
            }
            val result = response.body<RootBean<T>>()
            if (result.status == API_CODE_SUCCESS) {
                emit(result.data as T)
            } else {
                throw HApiException(result.message, result.status).apply {
                    data = Json.encodeToString(result)
                }
            }
        }.catch { throwable: Throwable ->
            throw throwable
        }.flowOn(Dispatchers.IO)
    }

    inline fun <reified T> post(url: String, request: Any): Flow<T> {
        return flow {
            val response = client.post("${BASE_API_URL}${url}") {
                setBody(request)
            }
            val result = response.body<RootBean<T>>()
            if (result.status == API_CODE_SUCCESS) {
                emit(result.data as T)
            } else {
                throw HApiException(result.message, result.status).apply {
                    data = Json.encodeToString(result)
                }
            }
        }.catch { throwable: Throwable ->
            throw throwable
        }.flowOn(Dispatchers.IO)
    }
}